#ifndef MUSICLIB_H_
#define MUSICLIB_H_

#include "globals.h"
#include "fat32.h"
//#include <stdint.h>

// Record structures used by music library file.
// Used to read and parse file
typedef struct SongRecord_s
{
	uint8_t filename[11];
	uint8_t songname[30];
} SongRecord_t;

typedef struct AlbumRecord_s
{
	uint8_t albumname[30];
	uint16_t songs;
	uint16_t songindex;
} AlbumRecord_t;

typedef struct ArtistRecord_s
{
	uint8_t aristname[30];
	uint16_t albums;
	uint16_t albumindex;
	uint16_t songs;
	uint16_t songindex;
} ArtistRecord_t;

typedef struct MusicLibHeader_s
{
	uint8_t header[12]; // Equals MUSICLIBv0.1
	uint16_t artists;
	uint16_t albums;
	uint16_t songs;
} MusicLibHeader_t;

/*	Enumeration used to keep track of where in the menu system
	We are and to keep track of how to interpret data */
enum MusicLibMenuDepth_t
{
	MAIN_MENU = 0,
	CURRENT_SONG,
	ARTIST_SORT,
	ARTIST_ALBUM_SORT,
	ARTIST_ALBUM_SONG_SORT,
	ALBUM_SORT,
	ALBUM_SONG_SORT,
	SONG_SORT
};

// Used to hold info for song currently begin decoded by vs1053
typedef struct CurrentPlaybackInfo_s
{
	uint16_t count;
	uint16_t num;
	ArtistRecord_t artistrec;
	AlbumRecord_t albumrec;
	SongRecord_t songrec;

} CurrentPlaybackInfo_t;

/*	Music library info struct
	Holds data and state condition of menu system */
typedef struct MusicLib_s
{
	MusicLibHeader_t libHeader; // Contains info found in header of lib file

	FAT_FILE_t * fp; // Local file pointer to lib file

	uint8_t buf[512]; // Local data buffer

	uint16_t AlbumOffset; // Precomputed album data section offset

	uint16_t SongOffset; // Precomputed song data section offset

	ArtistRecord_t currentArtist; // Temp artist record holder

	AlbumRecord_t currentAlbum; // Temp Album Record Holder

	SongRecord_t currentSong; // Temp Song Record Holder

	enum MusicLibMenuDepth_t menu_depth; // Menu Depth state

	uint16_t cursorPos[4]; // Layered cursor position array (allows for remembering
						   // where we should point when the back button is pressed)

	uint8_t playback_type; // Specifies how to hand getnext/getprev functions work

	CurrentPlaybackInfo_t current; // Contains info for currently decoding song

}MusicLib_t;

typedef enum MusicLibCommand_s
{
	LIB_SELECT = 0,
	LIB_BACK,
	LIB_UP,
	LIB_DOWN
} MusicLibCommand_t;

typedef enum ButtonAction_s
{
	NO_ACTION = 0,
	NEW_SONG_SELECTED,
	SONG_NEXT,
	SONG_PREV,
	PAUSE_PLAY,
	INCR_VOL,
	DECR_VOL
} ButtonAction_t;

/****************************************************************************
* Purpose:	Initalizes the menu system.
* Input:	No Input
* Output:   Returns 1 on success, 0 on failure
****************************************************************************/
uint8_t initMusicLib(void);

/****************************************************************************
* Purpose:	Resets the music lib to inital state. Called when sd card is
*			removed
* Input:	No Input
* Output:   No Output
****************************************************************************/
void	disableMusicLib(void);

/****************************************************************************
* Purpose:	Passes a input button to the menu system for interpretation
* Input:	Library Naviagtion command (LIB_UP, LIB_BACK, etc)
* Output:   Returns action that state machine should perform if any
****************************************************************************/
ButtonAction_t navigate(MusicLibCommand_t command);

/****************************************************************************
* Purpose:	Gets the current song selection for playback
* Input:	None
* Output:   Returns a valid fileptr on success, null on failure
****************************************************************************/
FAT_FILE_t * getSelection(void);

/****************************************************************************
* Purpose:	Gets the next song selection for playback
* Input:	None
* Output:   Returns a valid fileptr on success, null on failure
****************************************************************************/
FAT_FILE_t * getNextSong(void);

/****************************************************************************
* Purpose:	Gets the prev song selection for playback
* Input:	None
* Output:   Returns a valid fileptr on success, null on failure
****************************************************************************/
FAT_FILE_t * getPrevSong(void);

/****************************************************************************
* Purpose:	Updates the display
* Input:	None
* Output:   None
****************************************************************************/
void updateDisplay(void);

/****************************************************************************
* Purpose:	Performs a LIB_SELECT action
* Input:	None
* Output:   Returns action that system needs to perform
****************************************************************************/
ButtonAction_t doLibSelect(void);

/****************************************************************************
* Purpose:	Performs a LIB_BACK action
* Input:	None
* Output:   None
****************************************************************************/
void doLibBack(void);

/****************************************************************************
* Purpose:	Performs a LIB_UP action
* Input:	None
* Output:   Returns action that system needs to perform
****************************************************************************/
ButtonAction_t doLibUp(void);

/****************************************************************************
* Purpose:	Performs a LIB_DOWN action
* Input:	None
* Output:   Returns action that system needs to perform
****************************************************************************/
ButtonAction_t doLibDown(void);

/****************************************************************************
* Purpose:	Loads a song record into record pointer "rec" according to
*			menu state.
* Input:	Pointer to Song Record
* Output:   None
****************************************************************************/
void getSongRecord(SongRecord_t * rec);

/****************************************************************************
* Purpose:	Loads a album record into record pointer "rec" according to
*			menu state.
* Input:	Pointer to Album Record
* Output:   None
****************************************************************************/
void getAlbumRecord(AlbumRecord_t * rec);

/****************************************************************************
* Purpose:	Loads a artist record into record pointer "rec" according to
*			menu state.
* Input:	Pointer to Artist Record
* Output:   None
****************************************************************************/
void getArtistRecord(ArtistRecord_t * rec);

/****************************************************************************
* Purpose:	Clears the display
* Input:	None
* Output:   None
****************************************************************************/
void displayClear(void);

/****************************************************************************
* Purpose:	Writes a string to the display
* Input:	Pointer to unsigned string
* Output:   None
****************************************************************************/
void displayWrite(uint8_t * str);

/****************************************************************************
* Purpose:	Loads current.songrec with valid record information
*			depeding on playback_method
* Input:	Pointer to song record
* Output:   None
****************************************************************************/
void getPlaybackSongRecord(SongRecord_t * rec);

#endif /* MUSICLIB_H_ */